package com.hugedata.cdn.util;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.hugedata.cdn.service.task.bean.NodeBean;
import com.hugedata.cdn.service.task.bean.TaskBean;
import com.hugedata.cdn.service.task.impl.TaskService;

/**
 * 项目名称：cdn 类名称：CommonUtil 类描述： 创建人：zhaoaihua 创建时间�?013-3-20 上午9:26:07 修改备注�?
 * @version
 */
public class CommonUtil
{
 
    // 任务全局map
    private static final Map<String, TaskBean> GOL_TASKS = Collections
            .synchronizedMap(new HashMap<String, TaskBean>());

    // node全局map
    private static final Map<String, NodeBean> GOL_NODES = Collections
            .synchronizedMap(new HashMap<String, NodeBean>());

    // 区域节点全局map
    private static final Map<String, List<NodeBean>> GOL_CODENODES = Collections
            .synchronizedMap(new HashMap<String, List<NodeBean>>());

    // nodeId--code map
    private static final Map<String, String> GOL_CODENODEIDMAP = Collections
            .synchronizedMap(new HashMap<String, String>());

    // 区域节点全局map
    private static final List<String> GOL_BASISNODES = Collections
            .synchronizedList(new ArrayList<String>());

    // 全局任务节点列表map 暂不考虑保存节点详情信息
    // private static final Map<String, List<NodeBean>> GOL_TNMAP = Collections
    // .synchronizedMap(new HashMap<String, List<NodeBean>>());
    private static final Map<String, Integer> GOL_TNMAP = Collections
            .synchronizedMap(new HashMap<String, Integer>());

    private static final Map<String, String> GOL_NODENAME = Collections
            .synchronizedMap(new HashMap<String, String>());

    private static final ScheduledExecutorService singleScheduleExecutor = Executors.newSingleThreadScheduledExecutor();
    
    private static final ExecutorService BILL_TASKPOOL = Executors.newFixedThreadPool(128);
    
    private static final ExecutorService taskpush_TASKPOOL = Executors.newFixedThreadPool(128);

    private TaskService taskServce;

    protected final Log log = LogFactory.getLog(getClass());

    public void init() throws CdnException
    {
        try
        {
            // 初始化全局task
            List<TaskBean> tasks = taskServce.findTasks();
            for (TaskBean task : tasks)
            {
                // task.formatNickName();
                // GOL_TASKS.put(task.getTaskID(), task);
                addTaskBean(task);
                GOL_TNMAP.put(task.getTaskID(),
                        taskServce.countNodesByTaskid(task.getTaskID()));
            }

            // 初始化全�?ode
            List<NodeBean> nodes = taskServce.findNodes();
            for (NodeBean node : nodes)
            {
                GOL_NODES.put(node.getNodeID(), node);
                String name = taskServce.findNodeNameByID(node.getNodeID());
                if (null != name)
                {
                    GOL_NODENAME.put(node.getNodeID(), name);
                }
            }

        }
        catch (CdnException e)
        {

            log.error("ret = " + ResultCode.initDataFormDBError
                    + "--when XMF startup error,  init data form db error");

            throw new CdnException(ResultCode.initDataFormDBError, e);
        }

    }

    /**
     * getNodeNameBynodeID 根据node获取�?��Node info
     * @param nodeID
     * @return NodeBean
     * @CdnException 异常对象
     */
    public String getNodeNameBynodeID(String nodeID) throws CdnException
    {

        String name = GOL_NODENAME.get(nodeID);

        if (null == name)
        {
            name = taskServce.findNodeNameByID(nodeID);

            GOL_NODENAME.put(nodeID, name);
        }

        return name;
    }

    /**
     * getNodeBean 根据node获取�?��Node info
     * @param nodeID
     * @return NodeBean
     * @CdnException 异常对象
     */
    public int getNodeNumByTaskID(String taskID) throws CdnException
    {

        Integer count = GOL_TNMAP.get(taskID);

        if (null == count || 0 == count)
        {
            count = taskServce.countNodesByTaskid(taskID);

            if (null != count)

                GOL_TNMAP.put(taskID, count);
        }

        if (null == count)
            return 0;

        return count;
    }

    /**
     * addTNmap
     */
    public void addTNmap(String taskID, int count)
    {

        GOL_TNMAP.put(taskID, count);
    }

    /**
     * addTNmap
     */
    public void addTNmap(String taskID)
    {

        Integer count = GOL_TNMAP.get(taskID);

        if (null != count)
        {

            GOL_TNMAP.put(taskID, count + 1);

        }

        GOL_TNMAP.put(taskID, 1);
    }

    /**
     * delTNMap
     */
    public void delTNMap(String taskID)
    {

        if (null != taskID)
            GOL_TNMAP.remove(taskID);
    }

    /**
     * modTNMap
     */
    public void modTNMap(String taskID, int count)
    {

        GOL_TNMAP.put(taskID, count);

    }

    /**
     * getNodesBasis 获取基准测量�?
     * @param nameCode
     * @return List<NodeBean>
     * @CdnException 异常对象
     */
    public List<String> getNodesBasis() throws CdnException
    {

        if (GOL_BASISNODES.size() == 0)
        {

            List<String> nodes = taskServce.getNodesBasis();

            GOL_BASISNODES.addAll(nodes);
        }

        return GOL_BASISNODES;
    }

    /**
     * getNodeCodeByNodeID 根据nodeid 获取 节点�?��区域code
     * @param nameCode
     * @return List<NodeBean>
     * @CdnException 异常对象
     */
    public String getNodeCodeByNodeID(String nodeId) throws CdnException
    {

        String codeId = GOL_CODENODEIDMAP.get(nodeId);

        if (null == codeId)
        {

            codeId = taskServce.findNodeCodeByNodeID(nodeId);

            GOL_CODENODEIDMAP.put(nodeId, codeId);
        }

        return codeId;
    }

    /**
     * delCodeNodes 删除code到全�?ap
     */
    public void delNodeCodeByNodeID(String nodeId)
    {

        if (null != nodeId)
            GOL_CODENODEIDMAP.remove(nodeId);
    }

    /**
     * getCodeNodes 根据code获取该区域的探测节点
     * @param nameCode
     * @return List<NodeBean>
     * @CdnException 异常对象
     */
    public List<NodeBean> getCodeNodes(String nameCode) throws CdnException
    {

        List<NodeBean> beans = GOL_CODENODES.get(nameCode);

        if (null == beans)
        {
            beans = taskServce.getNodesbyCode(nameCode);

            GOL_CODENODES.put(nameCode, beans);
        }

        return beans;
    }

    /**
     * delCodeNodes 删除code到全�?ap
     */
    public void delCodeNodes(String nameCode)
    {

        if (null != nameCode)
            GOL_CODENODES.remove(nameCode);
    }

    /**
     * getTaskBean 根据taskid获取�?��task
     * @param taskID
     * @return TaskBean
     * @CdnException 异常对象
     */
    public TaskBean getTaskBean(String taskID) throws CdnException
    {

        TaskBean bean = GOL_TASKS.get(taskID);

        if (null == bean)
        {
            bean = taskServce.findTaskinfoByID(taskID);
            GOL_TASKS.put(taskID, bean);
        }
        else
        {
            String imspTaskId = bean.getImspTask();
            if (StringUtils.equals("0", imspTaskId) || StringUtils.isBlank(imspTaskId))
            {
                bean = taskServce.findTaskinfoByID(taskID);
                GOL_TASKS.put(taskID, bean);
            }
        }

        return bean;
    }

    /**
     * addTaskBean 增加task到全�?ap
     */
    public void addTaskBean(TaskBean bean)
    {

        if (null != bean)
        {

            GOL_TASKS.put(bean.getTaskID(), bean);
        }

    }

    /**
     * delTaskBean 删除task到全�?ap
     */
    public void delTaskBean(String taskID)
    {

        if (null != taskID)
            GOL_TASKS.remove(taskID);
    }

    /**
     * modTaskBean 修改task到全�?ap
     */
    public void modTaskBean(TaskBean bean)
    {

        if (null != bean)
        {

            GOL_TASKS.put(bean.getTaskID(), bean);
        }

    }

    /**
     * addNodeBean 增加node到全�?ap
     */
    public void addNodeBean(NodeBean bean)
    {

        if (null != bean)
            GOL_NODES.put(bean.getNodeID(), bean);
    }

    /**
     * delNodeBean 删除node到全�?ap
     */
    public void delNodeBean(NodeBean bean)
    {

        if (null != bean)
            GOL_NODES.remove(bean.getNodeID());
    }

    /**
     * modNodeBean 修改node到全�?ap
     */
    public void modNodeBean(NodeBean bean)
    {

        if (null != bean)
            GOL_NODES.put(bean.getNodeID(), bean);
    }

    /**
     * getNodeBean 根据node获取�?��Node info
     * @param nodeID
     * @return NodeBean
     * @CdnException 异常对象
     */
    public NodeBean getNodeBean(String nodeID) throws CdnException
    {

        NodeBean bean = GOL_NODES.get(nodeID);

        if (null == bean)
        {
            bean = taskServce.findNodeinfoByNodeID(nodeID);
            GOL_NODES.put(nodeID, bean);
        }

        return bean;
    }

    /**
     * getSuitedNode 选取某个区域合�?的探测节�?
     * @param nodeCode
     * @return String 节点编号
     * @throws CdnException
     * @CdnException 异常对象
     */
    public String getSuitedNode(String nodeCode) throws CdnException
    {

        List<NodeBean> nodes = getCodeNodes(nodeCode);

        if (null != nodes && nodes.size() > 0)
        {

            if (nodes.size() == 1)
            {

                NodeBean node = nodes.get(0);

                return node.getNodeID();
            }
            else
            {

                NodeBean node = getSuitedNode(nodes);

                return node.getNodeID();
            }

        }
        else
        {

            return null;
        }

    }

    private NodeBean getSuitedNode(List<NodeBean> nodes) throws CdnException
    {

        NodeBean getBean = null;

        for (NodeBean bean : nodes)
        {

            if (getBean == null)
            {
                getBean = bean;
                continue;
            }

            if (bean.getTaskNum() < getBean.getTaskNum())
            {
                getBean = bean;
            }

        }

        return getBean;

    }

    /**
     * getSuitedNode 选取某个区域合�?的探测节�?
     * @param nodeCode
     * @return String 节点编号
     * @throws CdnException
     * @CdnException 异常对象
     */
    public void updateSuitedNodeTaskNUm(String nodeId) throws CdnException
    {

        String nodeCode = getNodeCodeByNodeID(nodeId);

        List<NodeBean> nodes = getCodeNodes(nodeCode);

        if (null != nodes && nodes.size() > 0)
        {

            if (nodes.size() == 1)
            {

                NodeBean node = nodes.get(0);
                node.setTaskNum(node.getTaskNum() + 1);

            }
            else
            {

                for (NodeBean bean : nodes)
                {
                    if (bean.getNodeID().equalsIgnoreCase(nodeId))
                    {

                        bean.setTaskNum(bean.getTaskNum() + 1);
                        break;
                    }
                }

            }

        }

    }

    /**
     * getNowTimestamp 获取当前时间�?
     * @return String
     * @Exception 异常对象
     * @since CodingExample�?er(编码范例查看) 1.1
     */
    public static String getNowTimestamp(String format)
    {

        SimpleDateFormat sp = new SimpleDateFormat(format);
        return sp.format(new Date());

    }

    /**
     * formatTimes 格式化输入时�?
     * @return String
     * @throws CdnException
     * @Exception 异常对象
     * @since CodingExample�?er(编码范例查看) 1.1
     */
    public static String formatTimes(String timediff) throws CdnException
    {

        try
        {

            StringBuffer sb = new StringBuffer();

            String[] times = timediff.split(":");
            int hourStr = Integer.parseInt(times[0]);
            int minuteStr = Integer.parseInt(times[1]);

            if (hourStr > 0)
            {
                sb.append(hourStr);
                sb.append("小时");
            }

            if (minuteStr > 0)
            {
                sb.append(minuteStr);
                sb.append("秒");
            }

            return sb.toString();
        }
        catch (Exception e)
        {

            throw new CdnException(ResultCode.SystemRunError,
                    "parse timeinterval error", e);
        }

    }

    /**
     * div 除法运算，保留scale�?
     * @param int 被除�?
     * @param int 除数
     * @param scale 小数点后位数
     * @return double
     * @Exception 异常对象
     */
    public static double div(int v1, int v2, int scale)
    {

        if (scale < 0)
        {

            throw new IllegalArgumentException(

            "The scale must be a positive integer or zero");

        }

        BigDecimal b1 = new BigDecimal(Double.toString(v1));

        BigDecimal b2 = new BigDecimal(Double.toString(v2));

        return b1.divide(b2, scale, BigDecimal.ROUND_DOWN).doubleValue();

    }

    /**
     * 获取话单组件线程池
     * @return 话单组件线程池
     */
    public static ExecutorService billTaskPool()
    {
        return BILL_TASKPOOL;
    }

    /**
     * 获取话单组件线程池
     * @return 话单组件线程池
     */
    public ExecutorService taskPushTaskPool()
    {
        return taskpush_TASKPOOL;
    }

    /**
     * 格式化string
     * @return String
     */
    public String StringFormat(String str, int strLength)
    {
        int strLen = str.length();
        if (strLen < strLength)
        {
            while (strLen < strLength)
            {
                StringBuffer sb = new StringBuffer();
                sb.append("0").append(str);// 左补0
                // sb.append(str).append("0");//右补0
                str = sb.toString();
                strLen = str.length();
            }
        }
        else
        {
            str = str.substring(strLen - strLength);
        }

        return str;
    }

    public String getTimestampFormat(String format, Date date)
    {

        SimpleDateFormat sp = new SimpleDateFormat(format);
        return sp.format(date);

    }

    public String getYearTimestampFormat(String format, Date date)
    {

        SimpleDateFormat sp = new SimpleDateFormat(format);

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        cal.add(Calendar.YEAR, 1);

        return sp.format(cal.getTime());

    }

    public static void main(String[] args)
    {
        // TODO Auto-generated method stub

        SimpleDateFormat sp = new SimpleDateFormat("yyyyMMddHHmmss");

        Date date1 = new Date();

        System.out.println(sp.format(date1));
        Calendar cal = Calendar.getInstance();
        cal.setTime(date1);

        cal.add(Calendar.YEAR, 1);
        Date date = cal.getTime();

        System.out.println(sp.format(date));

        System.out.println(CommonUtil.getNowTimestamp("yyyyMMddHHmmss"));

        System.out.println(div(4, 5, 2));

    }

    public void setTaskServce(TaskService taskServce)
    {
        this.taskServce = taskServce;
    }

    public static final ScheduledExecutorService getSingleScheduleExecutor()
    {
        return singleScheduleExecutor;
    }
}
